#pragma once
#include<iostream>
#include<cstdio>
#include<cerrno>
#include<cstring>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "log.hpp"

using namespace std;

#define PROJ 0x6666
#define SIZE_C 4096

const string path = "/home/Sean";

Log log(Onefile);

key_t get_key()
{
    key_t key = ftok(path.c_str(), PROJ);
    if(key < 0)
    {
        log(Fatal, "get key error:%s\n", strerror(errno));
        return -1;
    }
    log(Info, "get key success:%d\n", key);

    return key;
}

int shm_helper(key_t key, int flag)
{
    int shm_id = shmget(key, SIZE_C, flag);
    if(shm_id < 0)
    {
        log(Fatal, "shm_helper error:%s\n", strerror(errno));
        return -1;
    }

    return shm_id;
}

int create_shm()
{
    key_t key = get_key();
    //防止上次的通信异常退出，共享内存没有删除
    int shm_id = shmget(key, SIZE_C, 0666);
    if (shm_id >= 0) {
        log(Warning, "shm already exists, removing it\n");
        shmctl(shm_id, IPC_RMID, nullptr);
    }

    shm_id = shm_helper(key, IPC_CREAT | IPC_EXCL | 0666); //不存在就创建，存在就失败返回

    if(shm_id < 0)
    {
        log(Fatal, "create_shm error:%s\n", strerror(errno));
        return -1;
    }
    
    return shm_id;
}

int get_shm()
{
    key_t key = get_key();
    int shm_id = shm_helper(key, IPC_CREAT); //不存在就创建，存在就返回已存在的id
    if(shm_id < 0)
    {
        log(Fatal, "get_shm error:%s\n", strerror(errno));
        return -1;
    }
    
    return shm_id;
}

#define FIFO_FILE "./myfifo"
#define MODE 0664

enum
{
    FIFO_CREATE_ERR = 1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
};

class init_fifo //用于通知对方通信
{
    public:
        init_fifo()
        {
            int id = mkfifo(FIFO_FILE, 0664);
            if(id < 0)
            {
                log(Fatal, "mkfifo error:%s", strerror(errno));
            }
        }

        ~init_fifo()
        {
            int ret = unlink(FIFO_FILE);
            if(ret < 0)
            {
                log(Fatal, "unlink error:%s", strerror(errno));
            }
        }

};